package com.aya.aop.custom.afterthrow.pointcut;

import org.aopalliance.aop.Advice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.Pointcut;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.stereotype.Service;


@Service
public class MyAdvisor implements PointcutAdvisor {
    private static final Logger logger = LoggerFactory.getLogger(MyAdvisor.class);


    /**
     * 在 ThrowsAdvice 的注释上有说明 方法是什么样子的。
     * <p>
     * 从类型分为两种 public void afterThrowing(Exception ex)，
     * public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
     * 在  Exception 可以写具体的类型， 最大就是Throwable。
     * 由于是反射的方式，  所以 ThrowsAdvice 的实例对象必须是public的。 否则就会调用失败
     * 具体查找方式参考：
     *
     * @return
     * @see org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor#getExceptionHandler(java.lang.Throwable)
     * 在 ThrowsAdviceInterceptor 的构造方法规定了， 参数数量只能是 1 或者 4.
     * <p>
     * 写法方式：
     * * <pre class="code">public void afterThrowing(Exception ex)</pre>
     * * <pre class="code">public void afterThrowing(RemoteException)</pre>
     * * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, Exception ex)</pre>
     * * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)</pre>
     * *
     */
    @Override
    public Advice getAdvice() {
        return new MyThrowsAdvice();
    }

    @Override
    public boolean isPerInstance() {
        return true;
    }

    @Override
    public Pointcut getPointcut() {
        AspectJExpressionPointcut aspectJExpressionPointcut = new AspectJExpressionPointcut();
        aspectJExpressionPointcut.setExpression("execution(* com.aya.aop.custom.afterthrow.pointcut..*(..))");
        return aspectJExpressionPointcut;
    }
}
